"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

import Pyro.core
from msnp.service.network.logic import AuthenticationLogic, ResponsibilityLogic, \
    FingerLogic, PeerUpdateLogic, BackupLogic, CrashLogic, MessageExchangeLogic, \
    GroupManagementLogic


####################
## AUTHENTICATION ##
####################

class Authentication(Pyro.core.ObjBase):
    """Remote model for the authentication process."""
    
    def __init__(self):
        Pyro.core.ObjBase.__init__(self)
        
    def authenticate(self, identity, isLogin):
        """This function forwards the call to the AuthenticationLogic module.
    
        Args:
            identity: The new PeerInfo instance of the authenticating peer.
            isLogin: This boolean determines whether the new peer initiated a login or a registration.
        """
        AuthenticationLogic.executeAuthenticate(identity, isLogin)


###########################
## RESPONSIBILITY_SEARCH ##
###########################
        
class ResponsibilitySearch(Pyro.core.ObjBase):
    """Remote model for the responsibility search."""
    
    def __init__(self):
        Pyro.core.ObjBase.__init__(self)
    
    def findResponsibleIdentityForAuth(self, searchedName, superPeerIdentity, isLogin):
        """This function forwards the call to the ResponsibilityLogic module.
    
        Args:
            searchedName: The searched name (string)
            superPeerIdentity: the super peer identity (PeerInfo instance)
            isLogin: a boolean determining whether the executed authentication procedure is a registration or a login.
        """
        ResponsibilityLogic.executeFindResponsibleIdentityForAuth(searchedName, superPeerIdentity, isLogin)
        
    def callbackResponsibleIdentityForAuth(self, responsibleIdentity, receiverName, isLogin):
        """This function forwards the call to the ResponsibilityLogic module.
    
        Args:
            receiverName: the receiver name (string)
            responsibleIdentity: the responsible identity (PeerInfo instance)
            isLogin: a boolean determining whether the executed authentication procedure is a registration or a login.
        """
        ResponsibilityLogic.executeCallbackResponsibleIdentityForAuth(responsibleIdentity, receiverName, isLogin)
        
    def findResponsibleIdentity(self, receiverName, senderName, senderRespIdentity, reactType):
        """This function forwards the call to the ResponsibilityLogic module.
    
        Args:
            receiverName: the receiver name (string)
            senderName: the sender name (string)
            senderRespIdentity: the responsible identity of the sender (PeerInfo instance)
            reactType: the react type is forwarded to other functions
        """
        ResponsibilityLogic.executeFindResponsibleIdentity(receiverName, senderName, senderRespIdentity, reactType)
        
    def callbackResponsibleIdentity(self, receiverRespIdentity, senderName, receiverName, result, reactType):
        """This function forwards the call to the ResponsibilityLogic module.
    
        Args:
            receiverRespIdentity: the responsible identity of the receiver (PeerInfo instance)
            senderName: the sender name (string)
            receiverName: the receiver name (string)
            result: the result is forwarded to other functions
            reactType: the react type is forwarded to other functions
        """
        ResponsibilityLogic.executeCallbackResponsibleIdentity(receiverRespIdentity, senderName, receiverName, result, reactType)
    
    def callbackResponsibleIdentityForFinger(self, identity, lowerFingerIndex, upperFingerIndex):
        """This function forwards the call to the ResponsibilityLogic module.
    
        Args:
            identity: the received finger candidate (PeerInfo instance)
            lowerFingerIndex: the lower finger index (inclusive - integer)
            upperFingerIndex: the upper finger index (inclusive - integer)
        """
        ResponsibilityLogic.executeCallbackResponsibleIdentityForFinger(identity, lowerFingerIndex, upperFingerIndex)

    def findPredecessorOfCrashedIdentity(self, crashedIdentity, alreadyReceivedUsers):
        """This function forwards the call to the ResponsibilityLogic module.
    
        Args:
            crashedIdentity: the crashed identity (PeerInfo instance).
            alreadyReceivedUsers: a list containing peers that already received the message.
        """
        ResponsibilityLogic.executeFindPredecessorOfCrashedIdentity(crashedIdentity, alreadyReceivedUsers)
      

#################
## FINGERTABLE ##
#################

class Fingertable(Pyro.core.ObjBase):
    """Remote model for finger table modifications."""
    
    def __init__(self):
        Pyro.core.ObjBase.__init__(self)

    def updatePredecessorOfSuccessor(self, identity, isCrash):
        """This function forwards the call to the FingerLogic module.
    
        Args:
            identity: the PeerInfo instance.
            isCrash: This boolean determines if an underlying crash procedure is executed.
            
        Returns:
            Returns SUCCESSFUL, RECONNECT, FORCE_REHELLO or UPDATE_PREDECESSOR_ERROR.
        """
        return FingerLogic.executeUpdatePredecessorOfSuccessor(identity, isCrash)
    
    def getSuccessor(self):
        """This function forwards the call to the FingerLogic module.
    
        Returns:
            Returns the successor as PeerInfo instance.
        """
        return FingerLogic.executeGetSuccessor() 
        
        
#################
## PEER_UPDATE ##
#################

class PeerUpdate(Pyro.core.ObjBase):
    """Remote model for the upgrade process."""
    
    def __init__(self):
        Pyro.core.ObjBase.__init__(self)
        
    def superPeerAbilityTest(self, lowLevelPeer):
        """This function forwards the call to the PeerUpdateLogic module.
    
        Args:
            lowLevelPeer: The PeerInfo instance.
        """
        PeerUpdateLogic.executeSuperPeerAbilityTest(lowLevelPeer)
    
    def sendShiftedData(self, llPeerList, messages):
        """This function forwards the call to the PeerUpdateLogic module.
    
        Args:
            llPeerList: A list of low level peers (PeerInfo instances).
            messages: a list of CustodyMessage instances.
            
        Returns:
            The return is defined by ReturnType and be one of the following values: SUCCESSFUL or ERROR
        """
        return PeerUpdateLogic.executeSendShiftedData(llPeerList, messages)
        
    def joinRing(self, newSuccessor, newPredecessor):
        """This function forwards the call to the PeerUpdateLogic module.
    
        Args:
            newSuccessor: the successor (PeerInfo instance)
            newPredecessor: the predecessor (PeerInfo instance)
            
        Returns:
            The return is defined by ReturnType and be one of the following values: SUCCESSFUL or ERROR
        """
        return PeerUpdateLogic.executeJoinRing(newSuccessor, newPredecessor)
        
    def logoutLowLevelPeer(self, llPeerName):
        """This function forwards the call to the PeerUpdateLogic module.
    
        Args:
            llPeerName: the name of the leaving low level peer (string)
            
        Returns:
            False
        """
        return PeerUpdateLogic.executeLogoutLowLevelPeer(llPeerName)
        
    def getTimestamp(self):
        """This function forwards the call to the PeerUpdateLogic module.
    
        Returns:
            Returns the current time stamp as float.
        """
        return PeerUpdateLogic.executeGetTimestamp()
    
    def sendMessages(self, queueMessages):
        """This function forwards the call to the PeerUpdateLogic module.
    
        Args:
            queueMessages: The list of CustodyMessage instances.
        """
        PeerUpdateLogic.executeSendMessages(queueMessages)

############
## BACKUP ##
############

class Backup(Pyro.core.ObjBase):
    """Remote model for the backup functionalities."""

    def __init__(self):
        Pyro.core.ObjBase.__init__(self)
        
    def sendBackup(self, backupContent):
        """This function forwards the call to the BackupLogic module.
    
        Args:
            backupContent: The BackupContent instance.
        """
        BackupLogic.executeSendBackup(backupContent)
        
    def backupCallback(self, backups):
        """This function forwards the call to the BackupLogic module.
    
        Args:
            backups: The list of BackupContent instances.
        """
        BackupLogic.executeBackupCallback(backups)
    
    
###########
## CRASH ##
###########

class Crash(Pyro.core.ObjBase):
    """Remote model for the crash functionalities."""
    def __init__(self):
        Pyro.core.ObjBase.__init__(self)
        
    def rtMessageErrorCallback(self, rtMessage):
        """This function forwards the call to the CrashLogic module.
    
        Args:
            rtMessage: The ReliableTransportMessage instance.
        """
        CrashLogic.executeRTMessageErrorCallback(rtMessage)
        
    def reconnectRing(self, newSuccessor, rtMessage):
        """This function forwards the call to the CrashLogic module.
    
        Args:
            neSuccessor: The new successor (PeerInfo instance).
            rtMessage: The ReliableTransportMessage instance. 
        """
        CrashLogic.executeReconnectRing(newSuccessor, rtMessage)
        
    def sequentialDelivery(self, rtMsg, originalIdentity, alreadyReceivedUsers):
        """This function forwards the call to the CrashLogic module.
    
        Args:
            rtMsg: The ReliableTransportMessage instance.
            originalIdentity: The initiator of the message (PeerInfo instance)
            alreadyReceivedUsers: A list of peers that already received the message.
        """
        CrashLogic.executeRTMessage(rtMsg, originalIdentity, alreadyReceivedUsers)
        
    def broadcastMessage(self, broadcastMsg):
        """This function forwards the call to the CrashLogic module.
    
        Args:
            broadcastMsg: The ReliableTransportMessage instance.
        """
        CrashLogic.executeRTMessage(broadcastMsg)
        
    def callbackCrashBroadcast(self, crashedIdentity, answerIdentity, successorOfCrashPeerFound):
        """This function forwards the call to the CrashLogic module.
    
        Args:
            crashedIdentity: The PeerInfo instance of the crashed peer.
            answerIdentity: A PeerInfo instance.
            successorOfCrashPeerFound: A boolean determining whether the successor of the crashed peer is already found.
        """
        CrashLogic.executeCallbackCrashBroadcast(crashedIdentity, answerIdentity, successorOfCrashPeerFound)
        
######################
## MESSAGE_EXCHANGE ##
######################
        
class MessageExchange(Pyro.core.ObjBase):
    """Remote model for message exchanges"""
    
    def __init__(self):
        Pyro.core.ObjBase.__init__(self)
        
    def hello(self, identity, isLogin):
        """This function forwards the call to the MessageExchangeLogic module.
    
        Args:
            identity: the PeerInfo instance
            isLogin: A boolean determining whether the executed authentication is a registration or a login.
        """
        MessageExchangeLogic.executeHello(identity, isLogin)
        
    def forwardRingReport(self, ringReportEntries, fingerValidationDict, backupValidationDict, alreadyReceivedUsers, type):
        """This function forwards the call to the MessageExchangeLogic module.
    
        Args:
            ringReportEntries: all collected RingReportEntry instances
            fingerValidationDict: a dictinary for validating the fingertables
            backupValidationDict: a dictinary for validating the backups
            alreadyReceivedUsers: a list of peers that already received the message
            type: the report type (defined in RingReportType)
        """
        MessageExchangeLogic.executeForwardRingReport(ringReportEntries, fingerValidationDict, backupValidationDict, alreadyReceivedUsers, type)
            
    def forwardPersonalMessage(self, receiverName, senderName, senderRespIdentity, message, timestamp):
        """This function forwards the call to the MessageExchangeLogic module.
    
        Args:
            receiverName: the name of the receiver (string)
            senderName: the name of the sender (string)
            senderRespIdentity: the responsible identity of the sender (PeerInfo instance)
            message: the personal message (string)
            timestamp: the timestamp
        """
        MessageExchangeLogic.executeForwardPersonalMessage(receiverName, senderName, senderRespIdentity, message, timestamp)
        
    def callbackPersonalMessage(self, receiverRespIdentity, receiverName, senderName, timestamp, status): 
        """This function forwards the call to the MessageExchangeLogic module.
    
        Args:
            receiverRespIdentity: the responsible identity of the receiver (PeerInfo instance)
            receiverName: the name of the receiver (string)
            senderName: the name of the sender (string)
            timestamp: the timestamp
            status: the status 
        """
        MessageExchangeLogic.executeCallbackPersonalMessage(receiverRespIdentity, receiverName, senderName, timestamp, status)
        
    def keepAlive(self, llPeerName, queueType):
        """This function forwards the call to the MessageExchangeLogic module.
    
        Args:
            llPeerName: the name of the low level peer (string)
            queueType: the type defined by CustodyQueueType
            
        Returns:
            Returns a tuple containing a return type (defined by ReturnType) and a list of CustodyMessage instances.
        """
        return MessageExchangeLogic.executeKeepAlive(llPeerName, queueType) 
    
    def isAlive(self):
        """This function forwards the call to the MessageExchangeLogic module.
    
        Returns:
            True
        """
        return MessageExchangeLogic.executeIsAlive()
    
    def sendMediaContent(self, content, timestamp, receiverName):
        """This function forwards the call to the MessageExchangeLogic module.
    
        Args:
            content: the transmitted media content.
            timestamp: the timestamp
            receiverName: the name of the receiver (string)
        """
        MessageExchangeLogic.executeSendMediaContent(content, timestamp, receiverName)
    
    def pollMediaContentSinceLastSynch(self, senderIdentity, senderName, receiverName, group, timestamp):
        """This function forwards the call to the MessageExchangeLogic module.
    
        Args:
            senderIdentity: the sender identity (PeerInfo instance)
            senderName: the name of the sender (string)
            receiverName: the name of the receiver (string)
            group: the Group instance
            timestamp: the timestamp
        """
        MessageExchangeLogic.executePollMediaContentSinceLastSynch(senderIdentity, senderName, receiverName, group, timestamp)
    
######################
## GROUP_MANAGEMENT ##
######################
        
class GroupManagement(Pyro.core.ObjBase):
    """Remote model for the group management."""
    
    def __init__(self):
        Pyro.core.ObjBase.__init__(self)

    def getGroupsWithOwner(self, originalRespIdentity, originalName, ownername, groupname, displayname, genre, reactType):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            originalRespIdentity: The original identity (PeerInfo instance)
            originalName: the name of the original identity (string)
            ownername: the owner name (string)
            groupname: the group name (string)
            displayname: the display name (string)
            genre: the genre (string)
            reactType: determines how to react on the execution.
        """
        GroupManagementLogic.executeGetGroupsWithOwner(originalRespIdentity, originalName, ownername, groupname, displayname, genre, reactType)
        
    def getGroupsWithoutOwner(self, originalRespIdentity, originalName, alreadyReceivedUsers, groupname, displayname, genre, reactType):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            originalRespIdentity: The original identity (PeerInfo instance)
            originalName: the name of the original identity (string)
            alreadyReceivedUsers: a list containing all peers that already received the message
            groupname: the group name (string)
            displayname: the display name (string)
            genre: the genre (string)
            reactType: determines how to react on the execution.
        """
        GroupManagementLogic.executeGetGroupsWithoutOwner(originalRespIdentity, originalName, alreadyReceivedUsers, groupname, displayname, genre, reactType)
        
    def callbackGroups(self, originalName, groups, reactType, searchFinished):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            originalName: the name of the original identity (string)
            groups: a list containing Group instances
            reactType: determines how to react on the execution.
            searchFinished: a boolean that determines whether the search procedure is finished.
        """
        GroupManagementLogic.executeCallbackGroups(originalName, groups, reactType, searchFinished)

    def establishGroupForLowLevel(self, group):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            group: the Group instance
            
        Returns:
            Returns the group and a return value whether the establishment was successful or not.
        """
        return GroupManagementLogic.establishGroup(group)
    
    def changeGroupDetailsForLowLevel(self, group):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            group: the Group instance
            
        Returns:
            Returns whether the update was successful or not.
        """
        return GroupManagementLogic.changeGroupDetails(group)

    def getGroupsForLowLevel(self, llName):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            llName: the name of the low level peer (string)
            
        Returns:
            Returns a list of Group instances.
        """
        return GroupManagementLogic.getGroupsForUsername(llName)
    
    def getGroupsAndMessageCountForLowLevel(self, llName):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            llName: the name of the low level peer (string)
            
        Returns:
            Returns only already processed messages because the not processed once get put into the custody queue
            and the low level peer will process them.
        """
        return GroupManagementLogic.getGroupsAndMessageCountForUsername(llName)
    
    def addMember(self, ownername, membername, groupname, originalIdentity):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            ownername: the owner name (string).
            membername: the member name (string).
            groupname: the group name (string).
            originalIdentity: the PeerInfo instance.
        """
        GroupManagementLogic.executeAddMember(ownername, membername, groupname, originalIdentity)
        
    def callbackMemberStatusChanged(self, interestedName, membername, groupname, ownername, result, status):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            interestedName: or the member name, or the owner name (string).
            membername: the member name (string).
            groupname: the group name (string).
            ownername the owner name (string).
            result: the result
            status: the status
        """
        GroupManagementLogic.executeCallbackMemberStatusChanged(interestedName, membername, groupname, ownername, result, status)

    def setMemberStatus(self, respIdentity, originalName, membername, groupname, ownername, status):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            respIdentity: the responsible identity (PeerInfo instance).
            originalName: the name or the original identity (string).
            membername: the member name (string).
            groupname: the group name (string).
            ownername the owner name (string).
            status: the status
        """
        GroupManagementLogic.executeSetMemberStatus(respIdentity, originalName, membername, groupname, ownername, status)
    
    def getGroupsWithMembersToConfirmForLowLevel(self, llName):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            llName: the name of the low level peer (string)
            
        Returns:
            Returns a list of Group instances.
        """
        return GroupManagementLogic.getGroupsWithMembersToConfirmForLowLevel(llName)
    
    def getStoredMessagesForLowLevel(self, llName):
        """This function forwards the call to the GroupManagementLogic module.
    
        Args:
            llName: the name of the low level peer (string)
            
        Returns:
            Returns a list of MemberStatusChangedMessage instances.
        """
        return GroupManagementLogic.getStoredMessagesForUsername(llName)
    
